<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8"/>
    <meta http-equiv="Content-Type" content="text/html"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
    <meta name="applicable-device" content="pc"/>
    <meta name="renderer" content="webkit"/>
    <title>基本配置</title>
    <link rel="icon" href="https://www.ly.com/favicon.ico">
    <link rel="stylesheet" href="https://file.40017.cn/visa/visaauto/element@2.15.14/index.css">
    <script type="text/javascript" src="https://file.40017.cn/hubble/lib/vue/2.6.10/vue.min.js"></script>
    <script type="text/javascript" src="https://js.40017.cn/touch/cn/public/jquery-1.8.3.min.js"></script>
    <script type="text/javascript" src="https://file.40017.cn/visa/visaauto/element@2.15.14/index.js"></script>
    <script type="text/javascript" src="../js/go.js"></script>
    <!--       <script type="text/javascript" src="./static/go.js"></script>-->
</head>
<style>
    body, html {
        margin: 0;
    }

    .dict-layout {
        min-height: 100vh;
        background: #f5f5f5;
        box-sizing: border-box;
    }

    .el-aside, .el-main {
        background-color: #fff;
        height: 100vh;

    }

    .el-aside {
        padding: 20px;
        overflow-y: scroll;
    }

    .el-aside .el-input .el-input__inner {
        height: 34px;
    }

    .el-aside .addRootButton .el-col .el-button {
        margin-bottom: 10px;
        margin-top: 10px;
    }

    .el-tree .el-tree-node__content {
        height: 36px;
        line-height: 36px;
        font-size: 15px;
    }

    .el-tree, .el-tree-node__expand-icon {
        color: #000;
        font-size: 16px;
    }

    .el-tree > .el-tree-node.is-drop-inner {
        background-color: #409EFF;
        color: #fff;
        border-radius: 3px;
    }

    .custom-tree-node .custom-tree-node-box {
        overflow: unset !important;
    }

    .custom-tree-node .custom-tree-node-box {
        position: absolute;
        background: #fff;
        position: absolute;
        left: 120px;
        text-align: center;
        border: 1px solid #409EFF;
        width: 50px;
        padding: 0px 20px;
        line-height: 26px;
        box-shadow: 0 4px 12px 0 rgba(0, 0, 0, .08);
        z-index: 1;
        top: 0;
        display: none;
    }

    .custom-tree-node .custom-tree-node-box div {
        color: #409EFF;
    }

    .custom-tree-node .custom-tree-node-box::after {
        position: absolute;
        content: "";
        width: 0;
        height: 0;
        border-left: 5px solid transparent;
        border-right: 5px solid transparent;
        border-bottom: 8px solid #409eff;
        left: 38px;
        top: -8px;
    }

    .el-main .el-row {
        min-height: 42px;
        margin-bottom: 10px;
    }

    .el-main .el-row .el-col .el-button {
        font-size: 16px;
        color: #000;
        font-weight: 700;
    }

    .resizeBox {
        width: 10px;
        cursor: ew-resize;
    }

    .el-table .el-table__header th.el-table__cell {
        background-color: #f0f7ff;
    }

    .el-pagination {
        text-align: right;
        margin-top: 20px;
    }

    .diagramBox {
        position: relative;
        padding-top: 60px;
        height: calc(100vh - 100px);
        box-sizing: border-box;
        overflow-y: scroll;
    }

    .diagramBox .saveButton {
        position: absolute;
        top: 0px;
        right: 20px;
        z-index: 999;
    }

    .diagramBox .direction-select {
        top: 50px;
        width: 105px;
    }

    .diagramBox .direction-select input {
        height: 25px;
        line-height: 25px;
    }

    .diagramBox .direction-select .el-input__suffix-inner .el-input__icon {
        line-height: 25px;
    }

    .diagramBox #myOverviewDiv {
        position: absolute;
        width: 200px;
        height: 100px;
        top: 100px;
        left: 36px;
        background-color: #f2f2f2;
        z-index: 300;
        border: solid 1px #7986cb;
    }

    .diagramBox .scrollBtn {
        font-weight: bold;
        position: absolute;
        left: 20px;
        top: 50%;
        left: 0;
        transform: translateY(-50%);
        z-index: 100;
        width: 26px;
        height: 100px;
        border: 1px solid #409EFF;
        color: #409EFF;
        background: #fff;
    }

    .diagramBox .scrollRightBtn {
        left: initial;
        right: 20px;
    }

    .diagramBox .scrollBtn i {
        font-size: 20px;
    }

    .ctxmenu {
        display: none;
        position: absolute;
        opacity: 0;
        margin: 0;
        padding: 8px 0;
        z-index: 999;
        box-shadow: 0 5px 5px -3px rgba(0, 0, 0, .2), 0 8px 10px 1px rgba(0, 0, 0, .14), 0 3px 14px 2px rgba(0, 0, 0, .12);
        list-style: none;
        background-color: #ffffff;
        border-radius: 4px;
    }

    .menu-item {
        display: block;
        position: relative;
        min-width: 60px;
        margin: 0;
        padding: 6px 16px;
        font: bold 14px sans-serif;
        color: rgba(0, 0, 0, .87);
        cursor: pointer;
        text-align: center;
    }

    .menu-item::before {
        position: absolute;
        top: 0;
        left: 0;
        opacity: 0;
        pointer-events: none;
        content: "";
        width: 100%;
        height: 100%;
        background-color: #000000;
    }

    .menu-item:hover::before {
        opacity: .04;
    }

    .show-menu, .menu-item:hover .ctxmenu {
        display: block;
        opacity: 1;
    }

</style>
<body>
<div id="app">
    <div class="dict-layout" @mousedown="menuVisible = false">
        <el-container>
            <el-aside>
                <el-row>
                    <el-col :span="24">
                        <el-input v-model="keyword" placeholder="请输入搜索词" clearable>
                            <el-button slot="append" icon="el-icon-search" @click="queryAsyncFlowNodeTree"></el-button>
                        </el-input>
                    </el-col>
                </el-row>
                <el-row class="addRootButton">
                    <el-col :span="24">
                        <el-button type="primary" size="small" @click="addRootLevel">新建根节点</el-button>
                    </el-col>
                </el-row>
                <el-tree :data="treeData" ref="syncTreeRef" :props="defaultProps" :highlight-current="true"
                         @node-click="handleNodeClick" node-key="name" :current-node-key="currentSelectNode"
                         :allow-drag="allowDrag" :allow-drop="allowDrop" @node-drop="nodeDrop" draggable
                         @node-drag-start="nodeDragStart" @node-contextmenu="rightClick"
                >
                    <template #default="{data,node}">
                        <div class="custom-tree-node">
                            <span v-if="data.type===2">{{ data.sort }}.{{data.des}}【{{ data.name }}】</span>
                            <span v- v-else-if="data.type===3">{{data.des}}【{{ data.name }}】</span>
                            <span v-else-if="data.type===4">{{data.des}}【{{ data.name }}】</span>
                            <span v-else>{{data.des}}:{{ data.name }}</span>
                            <div class="custom-tree-node-box"
                                 v-if="moveForm.dragKey == data.name && menuVisible && data.type==3">
                                <div @mousedown.stop="moveNode(data,node)">移动</div>
                            </div>
                        </div>
                    </template>
                </el-tree>
            </el-aside>
            <div class="resizeBox"></div>
            <el-main>

                <el-row>
                    <el-col :span="24">
                        <template v-if="selectLevelList && selectLevelList.length">
                            <el-button v-for="(item,index) in selectLevelList" :key="item.name"
                                       @click="selectLevel(item,index)" type="text">{{item.name}}
                                <template v-if="index != selectLevelList.length - 1">
                                    <i class="el-icon-arrow-right"></i>
                                </template>
                            </el-button>
                        </template>
                    </el-col>
                </el-row>
                <template v-if="showTable">
                    <el-table :data="tableData">
                        <el-table-column prop="name" label="模块名称" align="center"></el-table-column>
                        <el-table-column prop="des" label="模块描述" align="center"></el-table-column>
                    </el-table>
                    <el-pagination
                            v-model:current-page="currentPage"
                            :page-size="10"
                            layout="total, prev, pager, next, jumper"
                            :total="tableData.length"
                            @current-change="handleCurrentChange"
                    />
                </template>
                <template>
                    <!-- v-show="!showTable && nodeDataArray.length" -->
                    <div class="diagramBox" v-show="!showTable && nodeDataArray.length">
                        <el-button class="saveButton" @click="saveDiagram()" type="primary">代码编排</el-button>
                        <div class="saveButton direction-select">
                            <el-select v-model="direction" placeholder="请选择">
                                <el-option label="纵向陈列" :value="90"></el-option>
                                <el-option label="横向陈列" :value="0"></el-option>
                            </el-select>
                        </div>

                        <div id="myOverviewDiv"
                             style="-webkit-tap-highlight-color: rgba(255, 255, 255, 0); cursor: auto;"></div>
                        <div id="myDiagram"
                             style="height:calc(100% - 60px);width:calc(100% - 92px);margin-top: 40px;margin-left:36px;overflow: auto;"></div>
                        <el-button type="text" icon="el-icon-arrow-left" @click="handleScrollX('left')"
                                   class="scrollBtn"></el-button>
                        <el-button type="text" icon="el-icon-arrow-right" @click="handleScrollX('right')"
                                   class="scrollBtn scrollRightBtn"></el-button>
                        <ul id="contextMenu" class="ctxmenu">
                            <li id="copy" class="menu-item" @click="cxcommand('copy')">复制</li>
                            <li id="delete" class="menu-item" @click="cxcommand('delete')">删除</li>
                            <li id="addChild" class="menu-item" @click="cxcommand('addChild')">增加子节点</li>
                        </ul>
                    </div>
                    <div v-show="!showTable && !nodeDataArray.length">
                        <el-empty :image-size="200"></el-empty>
                    </div>
                </template>
            </el-main>

        </el-container>
    </div>
    <!-- 新增模块信息 -->
    <el-dialog title="新增" width="20%" :visible.sync="editModuleVisible">
        <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"
                 label-position="right">
            <el-form-item label="模块名称" prop="name">
                <el-input v-model="ruleForm.name" placeholder="请输入模块名称" clearable></el-input>
            </el-form-item>
            <el-form-item label="模块描述" prop="des">
                <el-input v-model="ruleForm.des" placeholder="请输入模块描述" clearable></el-input>
            </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
            <el-button @click="editModuleVisible = false">取 消</el-button>
            <el-button type="primary" @click="saveModule">确 定</el-button>
        </span>
    </el-dialog>
    <!-- 选择移动的位置 -->
    <el-dialog title="移动到" width="20%" :visible.sync="moveNodeVisible">
        <el-form :model="moveForm" ref="moveForm" label-width="100px" class="demo-ruleForm">
            <el-form-item label="移动到:" prop="dropKey"
                          :rules="[{ required: true, message: '请选择移动的位置', trigger: 'change'}]">
                <el-select v-model="moveForm.dropKey" placeholder="请选择移动的位置">
                    <el-option
                            v-for="(item,index) in canDropKeyList"
                            :key="item.name"
                            :label="item.name + item.des"
                            :value="item.name">
                    </el-option>
                </el-select>
            </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
            <el-button @click="moveNodeVisible = false">取 消</el-button>
            <el-button type="primary" @click="confirmMoveNode">确 定</el-button>
        </span>
    </el-dialog>
</div>
<script>
    new Vue({
        el: "#app",
        data() {
            return {
                urlPath: window.location.href.replace('/asyncFlowWeb/asyncFlowNodeTree', '/AsyncFlowAPI'),
                keyword: '',
                defaultProps: {
                    children: 'subModule_modelList',
                    label: 'name'
                },
                currentSelectNode: '',
                copyTreeData: [],
                selectLevelList: [],
                list: [],
                treeData: [
                    {
                        "name": "defaultParentModule",
                        "des": "默认",
                        "type": 2,
                        "subModule_modelList": [
                            {
                                "name": "PlusAsyncFlowTestManager",
                                "des": "测试异步流Plus",
                                "type": 3,
                                "subModule_modelList": [
                                    {
                                        "name": "Defaults",
                                        "des": null,
                                        "type": 4,
                                        "subModule_modelList": []
                                    },
                                    {
                                        "name": "PlusAsyncFlowTest",
                                        "des": null,
                                        "type": 4,
                                        "subModule_modelList": []
                                    }
                                ]
                            }
                        ]
                    },
                    {
                        "name": "defaultParentModule2",
                        "des": "默认2",
                        "type": 2,
                        "subModule_modelList": []
                    }
                ],
                currentPage: 1,
                total: 0,
                showTable: true,
                myDiagram: null,
                direction: 0,
                nodeDataArray: [
                    {
                        "key": "Start_Request",
                        "parent": "",
                        "name": "请求",
                        "source": "",
                        "description": "11111111111111111111111"
                    },
                    {
                        "key": "start_Validator",
                        "parent": "",
                        "name": "开始验证",
                        "source": "",
                        "fill": "green",
                        "description": "22222222222222222222222"
                    },
                    {
                        "key": "Test_Plus_1_Validator",
                        "parent": "",
                        "name": "测试异步流Plus验证1【false】",
                        "source": "",
                        "description": "3333333333333333333333"
                    },
                    {
                        "key": "start_GetData",
                        "parent": "",
                        "name": "开始查询",
                        "source": "",
                        "fill": "red"
                    },
                    {
                        "key": "Test_Plus_1_GetData",
                        "parent": "",
                        "name": "测试异步流Plus查询1【true】",
                        "source": ""
                    },
                    {
                        "key": "Test_Plus_2_GetData",
                        "parent": "",
                        "name": "测试异步流Plus查询2【true】",
                        "source": ""
                    },
                    {
                        "key": "start_Operator",
                        "parent": "",
                        "name": "开始操作",
                        "source": "",
                        "fill": "yellow"
                    },
                    {
                        "key": "Test_Plus_1_Operator",
                        "parent": "",
                        "name": "测试异步流Plus操作1【true】",
                        "source": ""
                    },
                    {
                        "key": "Test_Plus_2_Operator",
                        "parent": "",
                        "name": "测试异步流Plus操作2【true】",
                        "source": ""
                    },
                    {
                        "key": "Test_Plus_3_Operator",
                        "parent": "",
                        "name": "测试异步流Plus操作3【true】",
                        "source": ""
                    },
                    {
                        "key": "Test_Plus_4_Operator",
                        "parent": "",
                        "name": "测试异步流Plus操作4【true】",
                        "source": ""
                    },
                    {
                        "key": "Test_Plus_5_Operator",
                        "parent": "",
                        "name": "测试异步流Plus操作5【true】",
                        "source": ""
                    },
                    {
                        "key": "Test_Plus_6_Operator666",
                        "parent": "",
                        "name": "测试异步流Plus操作666【true】",
                        "source": ""
                    },
                    {
                        "key": "Test_Plus_7_Operator777",
                        "parent": "",
                        "name": "测试异步流Plus操作777【true】",
                        "source": ""
                    },
                    {
                        "key": "Test_Plus_8_Operator888",
                        "parent": "",
                        "name": "测试异步流Plus操作888【true】",
                        "source": ""
                    },
                    {
                        "key": "Test_Plus_8_Operator999",
                        "parent": "",
                        "name": "测试异步流Plus操作999【true】",
                        "source": ""
                    },
                    {
                        "key": "Test_Plus_6_Operator",
                        "parent": "",
                        "name": "测试异步流Plus操作6【false】",
                        "source": ""
                    },
                    {
                        "key": "Test_Plus_7_Operator",
                        "parent": "",
                        "name": "测试异步流Plus操作7【false】",
                        "source": ""
                    },
                    {
                        "key": "Test_Plus_8_Operator",
                        "parent": "",
                        "name": "测试异步流Plus操作8【false】",
                        "source": ""
                    },
                    {
                        "key": "Test_Plus_PubFlowNode_2_Operator",
                        "parent": "",
                        "name": "测试异步流公共节操作点1【true】",
                        "source": ""
                    },
                    {
                        "key": "Test_Plus_PubFlowNode_1_Operator",
                        "parent": "",
                        "name": "测试异步流公共节操作点1【true】",
                        "source": ""
                    },
                    {
                        "key": "TestTwo1Operator",
                        "parent": "",
                        "name": "11111【true】",
                        "source": ""
                    },
                    {
                        "key": "start_Async",
                        "parent": "",
                        "name": "开始异步",
                        "source": "",
                        "fill": "blue"
                    },
                    {
                        "key": "Test1Async",
                        "parent": "",
                        "name": "Test1【true】",
                        "source": "",
                        "fill": ''
                    },
                    {
                        "key": "Test2Async",
                        "parent": "",
                        "name": "Test2【true】",
                        "source": ""
                    },
                    {
                        "key": "Test3Async",
                        "parent": "",
                        "name": "Test3【true】",
                        "source": ""
                    },
                    {
                        "key": "End_Response",
                        "parent": "",
                        "name": "返回",
                        "source": ""
                    }
                ],
                linkDataArray: [
                    {
                        "from": "Start_Request",
                        "to": "start_Validator"
                    },
                    {
                        "from": "start_Validator",
                        "to": "Test_Plus_1_Validator"
                    },
                    {
                        "from": "Test_Plus_1_Validator",
                        "to": "start_GetData"
                    },
                    {
                        "from": "start_GetData",
                        "to": "Test_Plus_1_GetData"
                    },
                    {
                        "from": "start_GetData",
                        "to": "Test_Plus_2_GetData"
                    },
                    {
                        "from": "Test_Plus_1_GetData",
                        "to": "start_Operator"
                    },
                    {
                        "from": "Test_Plus_2_GetData",
                        "to": "start_Operator"
                    },
                    {
                        "from": "start_Operator",
                        "to": "Test_Plus_1_Operator"
                    },
                    {
                        "from": "start_Operator",
                        "to": "Test_Plus_2_Operator"
                    },
                    {
                        "from": "start_Operator",
                        "to": "Test_Plus_3_Operator"
                    },
                    {
                        "from": "start_Operator",
                        "to": "Test_Plus_4_Operator"
                    },
                    {
                        "from": "start_Operator",
                        "to": "Test_Plus_5_Operator"
                    },
                    {
                        "from": "start_Operator",
                        "to": "Test_Plus_6_Operator666"
                    },
                    {
                        "from": "start_Operator",
                        "to": "Test_Plus_7_Operator777"
                    },
                    {
                        "from": "start_Operator",
                        "to": "Test_Plus_8_Operator888"
                    },
                    {
                        "from": "start_Operator",
                        "to": "Test_Plus_8_Operator999"
                    },
                    {
                        "from": "Test_Plus_1_Operator",
                        "to": "Test_Plus_6_Operator"
                    },
                    {
                        "from": "Test_Plus_2_Operator",
                        "to": "Test_Plus_6_Operator"
                    },
                    {
                        "from": "Test_Plus_3_Operator",
                        "to": "Test_Plus_6_Operator"
                    },
                    {
                        "from": "Test_Plus_4_Operator",
                        "to": "Test_Plus_6_Operator"
                    },
                    {
                        "from": "Test_Plus_5_Operator",
                        "to": "Test_Plus_6_Operator"
                    },

                    {
                        "from": "Test_Plus_6_Operator666",
                        "to": "Test_Plus_6_Operator"
                    },
                    {
                        "from": "Test_Plus_7_Operator777",
                        "to": "Test_Plus_6_Operator"
                    },
                    {
                        "from": "Test_Plus_8_Operator888",
                        "to": "Test_Plus_6_Operator"
                    },
                    {
                        "from": "Test_Plus_8_Operator999",
                        "to": "Test_Plus_6_Operator"
                    },
                    {
                        "from": "Test_Plus_6_Operator",
                        "to": "Test_Plus_7_Operator"
                    },
                    {
                        "from": "Test_Plus_7_Operator",
                        "to": "Test_Plus_8_Operator"
                    },
                    {
                        "from": "Test_Plus_8_Operator",
                        "to": "Test_Plus_PubFlowNode_2_Operator"
                    },
                    {
                        "from": "Test_Plus_8_Operator",
                        "to": "Test_Plus_PubFlowNode_1_Operator"
                    },
                    {
                        "from": "Test_Plus_8_Operator",
                        "to": "TestTwo1Operator"
                    },
                    {
                        "from": "Test_Plus_PubFlowNode_2_Operator",
                        "to": "start_Async"
                    },
                    {
                        "from": "Test_Plus_PubFlowNode_1_Operator",
                        "to": "start_Async"
                    },
                    {
                        "from": "TestTwo1Operator",
                        "to": "start_Async"
                    },
                    {
                        "from": "start_Async",
                        "to": "Test1Async"
                    },
                    {
                        "from": "start_Async",
                        "to": "Test2Async"
                    },
                    {
                        "from": "start_Async",
                        "to": "Test3Async"
                    },
                    {
                        "from": "Test1Async",
                        "to": "End_Response"
                    },
                    {
                        "from": "Test2Async",
                        "to": "End_Response"
                    },
                    {
                        "from": "Test3Async",
                        "to": "End_Response"
                    }
                ],
                editModuleVisible: false,
                rules: {
                    name: [{required: true, message: '请输入模块名称', trigger: 'blur'}],
                    des: [{required: true, message: '请输入模块描述', trigger: 'blur'}]
                },
                ruleForm: {
                    name: '',
                    des: ''
                },
                menuVisible: false,
                moveNodeVisible: false,
                moveForm: {
                    dragKey: null,
                    dropKey: null
                },
                canDropKeyList: [],
                hasDeletedNodeList: []
            }
        },
        mounted() {
            this.dragTwoColBox()
            this.queryAsyncFlowNodeTree()
            // this.list=this.treeData
            // this.setProgram()
        },
        computed: {
            'tableData': function () {
                if (this.list && this.list.length) {
                    return this.list.slice((this.currentPage - 1) * 10, this.currentPage * 10)
                } else {
                    return []
                }

            }
        },
        watch: {
            'direction': function (val) {
                var myDiagram = this.myDiagram;
                this.myDiagram.startTransaction("change Layout");
                this.myDiagram.layout.isOngoing = true
                console.log(111, this.myDiagram.layout.direction)
                myDiagram.layout.direction = Number(val)
                this.myDiagram.commitTransaction("change Layout");
            }
        },
        methods: {
            queryAsyncFlowNodeTree() {
                const self = this;
                self.treeData = []
                self.list = []
                // this.openFullScreen2();
                $.ajax({
                    type: "POST",
                    url: this.urlPath + "/loadFlowTreeView",
                    dataType: "json",
                    data: {
                        keyword: self.keyword
                    },
                    contentType: "application/json",
                    success: function (result) {
                        if (result.subModule_modelList.length === 0) {
                            self.list = [];
                            self.treeData = [];
                        } else {
                            self.list = result.subModule_modelList || [];
                            self.treeData = result.subModule_modelList || [];
                        }
                        // self.loading.close();

                    }

                });
            },
            loadFlowTreeNodeGoJsInfo(managerName, managerModuleName) {
                const self = this;
                $.ajax({
                    type: "GET",
                    url: this.urlPath + "/loadFlowTreeNodeGoJsInfo",
                    // dataType: "json",
                    // contentType: "application/json",
                    data: "managerName=" + managerName + "&managerModuleName=" + managerModuleName,
                    success: function (result) {
                        if (result.goJsNodeEntityList.length === 0) {
                            self.nodeDataArray = [];
                            self.linkDataArray = [];
                        } else {
                            self.nodeDataArray = result.goJsNodeEntityList || [];
                            self.linkDataArray = result.goJsLinkDataEntityList || [];
                            self.setProgram()
                        }
                        // self.loading.close();

                    }

                });
            },
            dragTwoColBox() {
                let leftBox = document.querySelector('.dict-layout .el-aside')
                let rightBox = document.querySelector('.dict-layout .el-main')
                let resizeBox = document.querySelector('.dict-layout .resizeBox')
                let contentBox = document.querySelector('.dict-layout')

                resizeBox.onmousedown = function (e) {
                    let startX = e.clientX
                    resizeBox.setCapture && resizeBox.setCapture()
                    document.onmousemove = function (e) {
                        let endX = e.clientX
                        let leftBoxWidth = endX - startX + resizeBox.left
                        let totalWidth = contentBox.clientWidth - resizeBox.offsetWidth
                        if (leftBoxWidth < 100) {
                            leftBoxWidth = 100
                        }
                        leftBox.style.width = leftBoxWidth + 'px'
                        rightBox.style.width = Number(totalWidth - leftBoxWidth) + 'px'
                    }
                    resizeBox.left = resizeBox.offsetLeft;
                    document.onmouseup = function (e) {
                        document.onmousemove = null
                        document.onmouseup = null
                        resizeBox.releaseCapture && resizeBox.releaseCapture()
                    }
                    return false

                }
            },
            addRootLevel() {
                this.ruleForm = {
                    name: '',
                    des: ''
                }
                this.editModuleVisible = true
                this.$refs.ruleForm && this.$refs.ruleForm.resetFields() && this.$refs.ruleForm.clearValidate()
            },
            saveModule() {
                var self = this
                this.$refs.ruleForm.validate((valid) => {
                    if (valid) {
                        // 执行保存 参数为self.ruleForm  需要返回新增的模块信息  treeData push 进去返回的信息
                        $.ajax({
                            type: "GET",
                            url: this.urlPath + "/addModuleInfo",
                            //dataType: "json",
                            // contentType: "application/json",
                            data: "name=" + self.ruleForm.name + "&des=" + self.ruleForm.des,
                            success: function (result) {
                                console.log(result)
                                self.$message({
                                    type: 'info',
                                    message: result
                                });
                                self.ruleForm.sort = self.treeData[self.treeData.length - 1].sort + 1
                                self.treeData.push({...self.ruleForm, type: 2})
                            },
                            error: function (error) {

                                self.$message({
                                    type: 'error',
                                    message: error
                                })
                            }

                        });
                        self.editModuleVisible = false
                    } else {
                        console.log('error submit!!');
                        return false;
                    }
                });
            },
            moveNodeSync(managerName, managerModuleName, managerModuleNameDes) {
                var self = this
                $.ajax({
                    type: "GET",
                    url: this.urlPath + "/editManagerModuleInfo",
                    // dataType: "json",
                    // contentType: "application/json",
                    data: "managerName=" + managerName + "&managerModuleName=" + managerModuleName + "&managerModuleNameDes=" + managerModuleNameDes,
                    success: function (result) {
                        self.$message({
                            type: 'success',
                            message: result
                        });
                        self.moveNodeVisible = false
                        //self.queryAsyncFlowNodeTree()
                    },
                    error: function (error) {
                        if (!self.moveNodeVisible) {
                            self.treeData = self.copyTreeData
                        }
                        self.$message({
                            type: 'error',
                            message: '移动失败！请重试'
                        })
                    }
                })
            },
            setSelectLevelList(list) {
                return this.deepClone(list, [])
            },
            deepClone(list, typeList = []) {
                if (list && list.data && list.data.name && Object.prototype.toString.call(list.data) === '[object Object]') {
                    typeList.unshift(JSON.parse(JSON.stringify(list.data)))
                    if (list.parent) {
                        return this.deepClone(list.parent, typeList)
                    } else {
                        return typeList
                    }
                } else {
                    return typeList
                }
            },
            handleNodeClick(currentItem, levelList, c, d) {
                if (currentItem.type === 4) {
                    this.showTable = false
                    this.list = []
                    this.nodeDataArray = [];
                    this.linkDataArray = [];
                    this.loadFlowTreeNodeGoJsInfo(levelList.parent.data.name, currentItem.name);
                } else {
                    this.showTable = true
                }
                console.log(currentItem, "handleNodeClick")
                this.setTreeClick(currentItem, levelList)
            },
            // 点击tree的处理
            setTreeClick(currentItem, levelList) {
                this.currentSelectNode = currentItem.name
                this.selectLevelList = this.setSelectLevelList(levelList)
                this.getListByCurrentNode()
            },
            handleCurrentChange(val) {
                this.currentPage = val
            },
            // 表格上面的分类的tree类型点击
            selectLevel(item, index) {
                if (index === this.selectLevelList.length - 1) return
                this.currentSelectNode = item.name
                this.selectLevelList.splice(index + 1)
                this.getListByCurrentNode()
            },
            getListByCurrentNode() {
                this.currentPage = 1
                let node = this.$refs.syncTreeRef.getNode(this.currentSelectNode)
                if (node && node.data && node.data.subModule_modelList && node.data.subModule_modelList.length) {
                    this.list = node.data.subModule_modelList
                } else {
                    this.list = []
                }
            },
            nodeDragStart() {
                this.copyTreeData = JSON.parse(JSON.stringify(this.treeData))
            },
            allowDrag(draggingNode) {
                console.log(draggingNode, "是否允许拖拽")
                return draggingNode.data.type === 3;
            },
            allowDrop(draggingNode, dropNode, type) {
                console.log(draggingNode, dropNode, type, "是否能被放置")
                return dropNode.data.type === 2 && type === 'inner'
            },
            nodeDragEnd(draggingNode, dropNode, dropType, ev) {
                console.log('tree drag end: ', dropNode && dropNode.label, dropType);
            },
            nodeDrop(draggingNode, dropNode, dropType, ev) {
                const self = this;
                console.log(draggingNode, dropNode, dropType, ev, "拖拽完成")
                this.$confirm('是否移动' + draggingNode.data.name + '=>' + dropNode.data.name, '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    // 执行保存接口 移动的节点为draggingNode.data    当前位置为dropNode.data
                    self.moveNodeSync(draggingNode.data.name, dropNode.data.name, dropNode.data.des)
                }).catch(() => {
                    self.treeData = self.copyTreeData
                    self.$message({
                        type: 'info',
                        message: '取消移动'
                    });
                });
            },
            rightClick(event, currentItem, node, d) {
                console.log(event, currentItem, node, d, "右键")
                this.moveForm.dragKey = currentItem.name
                this.menuVisible = true
                setTimeout(() => {
                    let dom = document.querySelector('.custom-tree-node-box')
                    if (dom) {
                        dom.style.top = event.layerY + 10 + 'px'
                        dom.style.display = 'block'
                    }
                }, 100)


            },
            moveNode(data, node) {
                console.log(data, node)
                this.canDropKeyList = JSON.parse(JSON.stringify(this.treeData))
                let currentParentKey = node.parent && node.parent.data ? node.parent.data.name : null
                if (currentParentKey) {
                    let idx = this.canDropKeyList.findIndex(item => item.name === currentParentKey)
                    if (idx > -1) {
                        this.canDropKeyList.splice(idx, 1)
                    }
                }
                this.moveNodeVisible = true
                this.menuVisible = false

            },
            confirmMoveNode() {
                var self = this
                console.log(self.moveForm)
                this.$refs.moveForm.validate((valid) => {
                    if (valid) {
                        // this.canDropKeyList

                        let moveNode = {};
                        //找到当前需要移动的节点
                        for (var i = 0; i < self.treeData.length; i++) {
                            for (var j = 0; j < self.treeData[i].subModule_modelList.length; j++) {
                                console.log(self.treeData[i].subModule_modelList[j].name, self.moveForm.dragKey);
                                if (self.treeData[i].subModule_modelList[j].name === self.moveForm.dragKey) {
                                    moveNode = self.treeData[i].subModule_modelList[j];
                                    self.treeData[i].subModule_modelList.splice(j, 1)
                                    break;
                                }
                            }
                        }
                        // 将需要移动的节点放置到对应节点中
                        for (var i = 0; i < self.treeData.length; i++) {
                            if (self.treeData[i].name === self.moveForm.dropKey) {
                                self.treeData[i].subModule_modelList.push(moveNode)
                                break;
                            }
                        }
                        self.moveNodeSync(self.moveForm.dragKey, self.moveForm.dropKey, moveNode.des)
                    } else {
                        console.log('error submit!!');
                        return false;
                    }
                });
            },
            setProgram() {
                var self = this
                var Go = go.GraphObject.make;
                if (self.myDiagram) {
                    self.hasDeletedNodeList = []
                    self.myDiagram.div = null //重新渲染时需清空div
                }
                var myDiagram =
                    Go(go.Diagram, "myDiagram",
                        {
                            "undoManager.isEnabled": true,
                            // initialContentAlignment: go.Spot.Center,
                            layout: Go(go.LayeredDigraphLayout, {
                                direction: self.direction,
                                isOngoing: false,//新增的节点不随着布局变化
                            })
                        }
                    );
                // 解决两点之间多个连接 判断进出两个 ！！！！
                myDiagram.toolManager.linkingTool.linkValidation = (fromNode, fromPort, toNode, toPort) => {
                    console.log(fromNode.data.key, toNode.data.key, 111)
                    let toNodeInfo = myDiagram.findNodeForKey(toNode.data.key)
                    const links = toNodeInfo.findLinksConnected();
                    // console.log(links,fromNode.data)
                    // 是否已连接
                    let noLink = true
                    links.map(item => {
                        console.log(item.data, 916, fromNode.data.key)
                        if (item && item.data && item.data.from == fromNode.data.key) {
                            noLink = false
                        }
                    })
                    if (noLink) {
                        let fromNodeInfo = myDiagram.findNodeForKey(fromNode.data.key)
                        const links = fromNodeInfo.findLinksConnected();
                        links.map(item => {
                            console.log(item.data, 916, fromNode.data.key)
                            if (item && item.data && item.data.from == toNode.data.key) {
                                noLink = false
                            }
                        })
                    }
                    return noLink
                }
                var cxElement = document.getElementById("contextMenu");
                var myContextMenu = Go(go.HTMLInfo, {
                    show: showContextMenu,
                    hide: hideContextMenu
                });
                myDiagram.nodeTemplate =
                    Go(go.Node, "Spot",
                        {
                            contextMenu: myContextMenu,
                            selectionObjectName: 'BODY',
                            locationSpot: go.Spot.Center,
                            locationObjectName: "BODY"
                        },
                        new go.Binding("location", "loc", go.Point.parse),
                        Go(go.Panel, "Auto",
                            {name: "BODY", portId: ""},
                            Go(go.Shape, "RoundedRectangle",
                                {
                                    // fromLinkable: true, toLinkable: true, cursor: "pointer",
                                    fill: "#409EFF",
                                    stroke: null
                                },
                                new go.Binding("fill", "fill"),
                                new go.Binding("stroke", "fill")
                            ),
                            Go(go.Panel, "Vertical",
                                Go(go.Panel, "Horizontal",
                                    {margin: 8},
                                    Go(go.TextBlock, "Default Text",
                                        {
                                            margin: 12,
                                            stroke: "white",
                                            font: "bold 16px sans-serif",
                                            editable: true,
                                            "textEdited": function (tb, oldstr, newstr) {
                                                console.log(tb, 'textChanged')
                                                let editData = tb.part.data
                                                if (editData.key && editData.action != 1) {
                                                    // 对文本修改的节点增加标识
                                                    myDiagram.model.setDataProperty(editData, "action", 2);
                                                }
                                            }
                                        },
                                        new go.Binding("text", "name").makeTwoWay()
                                    ),
                                    Go("PanelExpanderButton", "INFO",
                                        {row: 0, column: 1, rowSpan: 2, margin: new go.Margin(0, 0, 0, 8)}
                                    )
                                ),
                                Go(go.Shape, "LineH",
                                    {
                                        stroke: "rgba(0, 0, 0, .60)", strokeWidth: 1,
                                        height: 1, stretch: go.GraphObject.Horizontal
                                    },
                                    new go.Binding("visible").ofObject("INFO")
                                ),
                                Go(go.Panel, "Vertical",
                                    {
                                        name: "INFO",
                                        stretch: go.GraphObject.Horizontal,
                                        margin: 8,
                                        defaultAlignment: go.Spot.Left,
                                    },
                                    Go(go.TextBlock, textStyle("description"),
                                        new go.Binding("text", "description", function (description) {
                                            return description;
                                        })
                                    )
                                )
                            ),
                        ),

                        makePort("T", go.Spot.Top, false, true),
                        makePort("L", go.Spot.Left, true, true),
                        makePort("R", go.Spot.Right, true, true),
                        makePort("B", go.Spot.Bottom, true, false),
                        {
                            mouseEnter: function (e, node) {
                                showSmallPorts(node, true);
                            },
                            mouseLeave: function (e, node) {
                                showSmallPorts(node, false);
                            }
                        },
                        Go("TreeExpanderButton", {
                            alignment: go.Spot.Right,
                            alignmentFocus: go.Spot.Left,
                            "ButtonBorder.figure": "Rectangle"
                        }),
                    );

                function textStyle(field) {
                    return [
                        {
                            font: "12px Roboto, sans-serif", stroke: "rgba(0, 0, 0, .60)",
                            visible: false
                        },
                        new go.Binding("visible", field, function (val) {
                            return val !== undefined;
                        })
                    ];
                }

                function makePort(name, spot, output, input) {
                    return Go(go.Shape, "Circle",
                        {
                            fill: null,
                            stroke: null,
                            desiredSize: new go.Size(10, 10),
                            alignment: spot,
                            alignmentFocus: spot,
                            portId: name,
                            fromSpot: spot, toSpot: spot,
                            fromLinkable: output, toLinkable: input,
                            cursor: "pointer"
                        }
                    );
                }

                function showSmallPorts(node, show) {
                    node.ports.each(function (port) {
                        if (port.portId !== "") {
                            port.fill = show ? "rgba(0,0,0,.3)" : null;
                        }
                    });
                }

                myDiagram.linkTemplate =
                    Go(go.Link,
                        go.Link.AvoidsNodes,
                        {layerName: "Background", curviness: 20, corner: 5},
                        Go(go.Shape, {strokeWidth: 2}),
                        Go(go.Shape, {toArrow: "Standard"})
                    );
                cxElement.addEventListener("contextmenu", function (e) {
                    e.preventDefault();
                    return false;
                }, false);

                function hideCX() {
                    if (myDiagram.currentTool instanceof go.ContextMenuTool) {
                        myDiagram.currentTool.doCancel();
                    }
                }

                function showContextMenu(obj, diagram, tool) {
                    var self = this
                    console.log(myDiagram.selection.first().data, '右击')
                    var cmd = diagram.commandHandler;
                    var hasMenuItem = false;

                    function maybeShowItem(elt, pred) {
                        if (pred) {
                            elt.style.display = "block";
                            hasMenuItem = true;
                        } else {
                            elt.style.display = "none";
                        }
                    }

                    maybeShowItem(document.getElementById("delete"), cmd.canDeleteSelection());
                    if (hasMenuItem) {
                        cxElement.classList.add("show-menu");
                        var mousePt = diagram.lastInput.viewPoint;
                        cxElement.style.left = mousePt.x + 5 + "px";
                        cxElement.style.top = mousePt.y + "px";
                    }
                    window.addEventListener("click", hideCX, true);
                }

                function hideContextMenu() {
                    cxElement.classList.remove("show-menu");
                    window.removeEventListener("click", hideCX, true);
                }

                myDiagram.model = new go.GraphLinksModel(this.nodeDataArray, this.linkDataArray)
                this.myDiagram = myDiagram
                let myOverview =
                    Go(go.Overview, "myOverviewDiv",
                        {observed: this.myDiagram, contentAlignment: go.Spot.Center});

            },
            cxcommand(val) {
                var self = this
                console.log('右击操作项')
                var myDiagram = this.myDiagram;
                var selection = this.myDiagram.selection.first()
                var selectedNode = JSON.parse(JSON.stringify(selection.data))
                console.log(selectedNode, selection.position, "当前选中的节点")

                switch (val) {
                    case "copy":
                        myDiagram.layout.isOngoing = false
                        myDiagram.model.addNodeData({
                            key: Math.random(),
                            name: selectedNode.name + 'copy',
                            loc: `${selection.position.x + 100} ${selection.position.y}`,
                            action: 1
                        });
                        break
                    case "delete":
                        myDiagram.layout.isOngoing = true;
                        if (selectedNode.action != 1) {
                            self.hasDeletedNodeList.push(selectedNode)
                            console.log(self.hasDeletedNodeList, 1025)
                        }
                        myDiagram.commandHandler.deleteSelection()
                        break;
                    case "addChild" :
                        myDiagram.layout.isOngoing = true;
                        let key = Math.random()
                        myDiagram.model.addNodeData({key: key, name: selectedNode.name + '的子节点', action: 1});
                        myDiagram.model.addLinkData({from: selectedNode.key, to: key});
                        break
                }
                myDiagram.currentTool.stopTool();
            },
            saveDiagram() {
                console.log('执行保存')
                console.log('已经删除的节点:', this.hasDeletedNodeList)
                this.myDiagram.model.modelData.position = go.Point.stringify(this.myDiagram.position);
                if (this.selectLevelList && this.selectLevelList.length === 3) {
                    let managerName = this.selectLevelList[1].name;
                    let operatorName = this.selectLevelList[2].name;
                    let goToUrl = window.location.href.replace("asyncFlowNodeTree", "codeGenerationWeb");
                    goToUrl = goToUrl + ("?managerName=" + managerName + "&operatorEnumName=" + operatorName);
                    window.open(goToUrl, '_blank')
                }
                console.log(this.myDiagram.model.toJson())
            },
            handleScrollX(type) {
                let x = type == 'left' ? -80 : 80
                let dom = document.querySelector('#myDiagram > div')
                let scrollDom = document.querySelector('#myDiagram > div > div')
                let maxScroll = 0
                if (scrollDom && dom) {
                    maxScroll = scrollDom.offsetWidth - dom.offsetWidth + 15
                }
                if (dom) {
                    if (!dom.scrollLeft && type == 'left') {
                        this.$message.warning('已呈现画布最左侧内容!')
                    } else if (maxScroll < dom.scrollLeft && type == 'right') {
                        this.$message.warning('已呈现画布最右侧内容！')
                    } else {
                        dom.scrollLeft = dom.scrollLeft + x
                    }
                }
            }

        }
    })
</script>
</body>
</html>